home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / games / nhak_src.zip / TOPL.C < prev    next >
C/C++ Source or Header  |  1993-03-16  |  8KB  |  412 lines

  1. /*    SCCS Id: @(#)topl.c    3.0    89/01/09
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #define NEED_VARARGS /* Uses ... */    /* comment line for pre-compiled headers */
  6. #include "hack.h"
  7.  
  8. STATIC_VAR char NEARDATA toplines[BUFSIZ];
  9.  
  10. #ifndef OVLB
  11. STATIC_DCL boolean no_repeat;
  12. #else /* OVLB */
  13. STATIC_OVL boolean no_repeat = FALSE;
  14. #endif /* OVLB */
  15.  
  16. extern xchar tlx, tly;
  17. #ifdef OVLB
  18. xchar tlx, tly;            /* set by pline; used by addtopl */
  19. #endif /* OVLB */
  20.  
  21. STATIC_DCL void NDECL(redotoplin);
  22. STATIC_DCL void FDECL(xmore,(const char *));
  23. STATIC_VAR struct topl {
  24.     struct topl *next_topl;
  25.     char *topl_text;
  26. } *old_toplines, *last_redone_topl;
  27.  
  28. #define    OTLMAX    20        /* max nr of old toplines remembered */
  29.  
  30. #ifdef OVL1
  31.  
  32. STATIC_OVL void
  33. redotoplin() {
  34.     home();
  35.     if(index(toplines, '\n')) cl_end();
  36.     if((*toplines & 0x80) && AS) {
  37.         /* kludge for the / command, the only time we ever want a */
  38.         /* graphics character on the top line */
  39.         putstr(AS);
  40.         xputc(*toplines);
  41.         putstr(AE);
  42.         putstr(toplines+1);
  43.     } else putstr(toplines);
  44.     cl_end();
  45.     tlx = curx;
  46.     tly = cury;
  47.     flags.toplin = 1;
  48.     if(tly > 1)
  49.         more();
  50. }
  51.  
  52. #endif /* OVL1 */
  53. #ifdef OVLB
  54.  
  55. int
  56. doredotopl(){
  57.     if(last_redone_topl)
  58.         last_redone_topl = last_redone_topl->next_topl;
  59.     if(!last_redone_topl)
  60.         last_redone_topl = old_toplines;
  61.     if(last_redone_topl){
  62.         Strcpy(toplines, last_redone_topl->topl_text);
  63.     }
  64.     redotoplin();
  65.     return 0;
  66. }
  67.  
  68. #endif /* OVLB */
  69. #ifdef OVL1
  70.  
  71. void
  72. remember_topl() {
  73.     register struct topl *tl;
  74.     register int cnt = OTLMAX;
  75.     if(last_redone_topl &&
  76.        !strcmp(toplines, last_redone_topl->topl_text)) return;
  77.     if(old_toplines &&
  78.        !strcmp(toplines, old_toplines->topl_text)) return;
  79.     last_redone_topl = 0;
  80.     tl = (struct topl *)
  81.         alloc((unsigned)(strlen(toplines) + sizeof(struct topl) + 3));
  82.     tl->next_topl = old_toplines;
  83.     tl->topl_text = (char *)(tl + 1);
  84.     Strcpy(tl->topl_text, toplines);
  85.     old_toplines = tl;
  86.     while(cnt && tl){
  87.         cnt--;
  88.         tl = tl->next_topl;
  89.     }
  90.     if(tl && tl->next_topl){
  91.         free((genericptr_t) tl->next_topl);
  92.         tl->next_topl = 0;
  93.     }
  94. }
  95.  
  96. void
  97. addtopl(s)
  98. const char *s;
  99. {
  100.     curs(tlx,tly);
  101.     if(tlx + strlen(s) > CO) putsym('\n');
  102.     putstr(s);
  103.     tlx = curx;
  104.     tly = cury;
  105.     flags.toplin = 1;
  106. }
  107.  
  108. #endif /* OVL1 */
  109. #ifdef OVL2
  110.  
  111. STATIC_OVL void
  112. xmore(s)
  113. const char *s;    /* allowed chars besides space/return */
  114. {
  115.     if(flags.toplin) {
  116.         curs(tlx, tly);
  117.         if(tlx + 8 > CO) putsym('\n'), tly++;
  118.     }
  119.  
  120.     if(flags.standout)
  121.         standoutbeg();
  122.     putstr("--More--");
  123.     if(flags.standout)
  124.         standoutend();
  125.  
  126.     xwaitforspace(s);
  127.     if(flags.toplin && tly > 1) {
  128.         home();
  129.         cl_end();
  130.         docorner(1, tly-1);
  131.         tlx = tly = 1;
  132.         curs(tlx, tly);
  133.     }
  134.     flags.toplin = 0;
  135. }
  136.  
  137. void
  138. more(){
  139.     xmore("");
  140. }
  141.  
  142. #endif /* OVL2 */
  143. #ifdef OVLB
  144.  
  145. void
  146. cmore(s)
  147. register const char *s;
  148. {
  149.     xmore(s);
  150. }
  151.  
  152. #endif /* OVLB */
  153. #ifdef OVL1
  154.  
  155. void
  156. clrlin(){
  157.     if(flags.toplin) {
  158.         home();
  159.         cl_end();
  160.         if(tly > 1) {
  161.             docorner(1, tly-1);
  162.             tlx = tly = 1;
  163.         }
  164.         remember_topl();
  165.     }
  166.     flags.toplin = 0;
  167. }
  168.  
  169. #endif /* OVL1 */
  170. #ifdef OVLB
  171.  
  172. /*VARARGS1*/
  173. /* Note that these declarations rely on knowledge of the internals
  174.  * of the variable argument handling stuff in "tradstdc.h"
  175.  */
  176.  
  177. #if defined(USE_STDARG) || defined(USE_VARARGS)
  178. void
  179. pline VA_DECL(const char *, line)
  180.     VA_START(line);
  181.     VA_INIT(line, char *);
  182.     vpline(line, VA_ARGS);
  183.     VA_END();
  184. }
  185.  
  186. # ifdef USE_STDARG
  187. void
  188. vpline(const char *line, va_list the_args) {
  189. # else
  190. void
  191. vpline(line, the_args) const char *line; va_list the_args; {
  192. # endif
  193.  
  194. #else  /* USE_STDARG | USE_VARARG */
  195.  
  196. void
  197. pline VA_DECL(const char *, line)
  198. #endif
  199.  
  200.     char pbuf[BUFSZ];
  201.     register char *bp = pbuf, *tl;
  202.     register int n,n0;
  203. /* Do NOT use VA_START and VA_END in here... see above */
  204.  
  205.     if(!line || !*line) return;
  206.     if(!index(line, '%')) Strcpy(pbuf,line); else
  207.     Vsprintf(pbuf,line,VA_ARGS);
  208.     if(no_repeat && flags.toplin == 1 && !strcmp(pbuf, toplines)) return;
  209.     nscr();        /* %% */
  210.  
  211.     /* If there is room on the line, print message on same line */
  212.     /* But messages like "You die..." deserve their own line */
  213.     n0 = strlen(bp);
  214.     if(flags.toplin == 1 && tly == 1 &&
  215.         n0 + strlen(toplines) + 3 < CO-8 &&  /* leave room for --More-- */
  216.         strncmp(bp, "You die", 7)) {
  217.         Strcat(toplines, "  ");
  218.         Strcat(toplines, bp);
  219.         tlx += 2;
  220.         addtopl(bp);
  221.         return;
  222.     }
  223.     if(flags.toplin == 1 && !strcmp(pbuf, toplines) &&
  224.         (n0 + strlen(toplines) + 3 >= CO-8)) {
  225.         more();
  226.         home();
  227.         putstr("");
  228.         cl_end();
  229.         goto again;
  230.     }
  231.     if(flags.toplin == 1) more();
  232.     else if(tly > 1) {    /* for when flags.toplin == 2 && tly > 1 */
  233.         docorner(1, tly-1);    /* reset tly = 1 if redraw screen */
  234.         tlx = tly = 1;    /* from home--cls() and docorner(1,n) */
  235.     }
  236. again:
  237.     remember_topl();
  238.     toplines[0] = 0;
  239.     while(n0){
  240.         if(n0 >= CO){
  241.             /* look for appropriate cut point */
  242.             n0 = 0;
  243.             for(n = 0; n < CO; n++) if(bp[n] == ' ')
  244.                 n0 = n;
  245.             if(!n0) for(n = 0; n < CO-1; n++)
  246.                 if(!letter(bp[n])) n0 = n;
  247.             if(!n0) n0 = CO-2;
  248.         }
  249.         (void) strncpy((tl = eos(toplines)), bp, n0);
  250.         tl[n0] = 0;
  251.         bp += n0;
  252.  
  253.         /* remove trailing spaces, but leave one */
  254.         while(n0 > 1 && tl[n0-1] == ' ' && tl[n0-2] == ' ')
  255.             tl[--n0] = 0;
  256.  
  257.         n0 = strlen(bp);
  258.         if(n0 && tl[0]) Strcat(tl, "\n");
  259.     }
  260.     redotoplin();
  261. }
  262.  
  263. /*VARARGS1*/
  264. void
  265. Norep VA_DECL(const char *, line)
  266.     VA_START(line);
  267.     VA_INIT(line, const char *);
  268.     no_repeat = TRUE;
  269.     vpline(line, VA_ARGS);
  270.     no_repeat = FALSE;
  271.     VA_END();
  272.     return;
  273. }
  274.  
  275. /*VARARGS1*/
  276. void
  277. You VA_DECL(const char *, line)
  278.     char *tmp;
  279.     VA_START(line);
  280.     VA_INIT(line, const char *);
  281.     tmp = (char *)alloc((unsigned int)(strlen(line) + 5));
  282.     Strcpy(tmp, "You ");
  283.     Strcat(tmp, line);
  284.     vpline(tmp, VA_ARGS);
  285.     free(tmp);
  286.     VA_END();
  287.     return;
  288. }
  289.  
  290. /*VARARGS1*/
  291. void
  292. Your VA_DECL(const char *,line)
  293.     char *tmp;
  294.     VA_START(line);
  295.     VA_INIT(line, const char *);
  296.     tmp = (char *)alloc((unsigned int)(strlen(line) + 6));
  297.     Strcpy(tmp, "Your ");
  298.     Strcat(tmp, line);
  299.     vpline(tmp, VA_ARGS);
  300.     free(tmp);
  301.     VA_END();
  302.     return;
  303. }
  304.  
  305. /*ARGSUSED*/
  306. /*VARARGS2*/
  307. void
  308. kludge  VA_DECL2(const char *, str, const char *, arg)
  309. #ifdef VA_NEXT
  310.     char *other1, *other2, *other3;
  311. #endif
  312.     VA_START(arg);
  313.     VA_INIT(str, const char *);
  314.     VA_INIT(arg, const char *);
  315. #ifdef VA_NEXT
  316.     VA_NEXT(other1, char *);
  317.     VA_NEXT(other2, char *);
  318.     VA_NEXT(other3, char *);
  319. # define OTHER_ARGS other1,other2,other3
  320. #else
  321. # define OTHER_ARGS arg1,arg2,arg3
  322. #endif
  323.     if(Blind || !flags.verbose) {
  324.         if(*str == '%') pline(str,"It",OTHER_ARGS);
  325.         else pline(str,"it",OTHER_ARGS);
  326.     } else pline(str,arg,OTHER_ARGS);
  327.     VA_END();
  328. }
  329.  
  330. #endif /* OVLB */
  331. #ifdef OVL0
  332.  
  333. void
  334. putsym(c)
  335. char c;
  336. {
  337.     switch(c) {
  338.     case '\b':
  339.         backsp();
  340.         curx--;
  341.         if(curx == 1 && cury > 1)
  342.             curs(CO, cury-1);
  343.         return;
  344.     case '\n':
  345.         curx = 1;
  346.         cury++;
  347.         if(cury > tly) tly = cury;
  348.         break;
  349.     default:
  350.         if(curx == CO)
  351.             putsym('\n');    /* 1 <= curx <= CO; avoid CO */
  352.         curx++;
  353.     }
  354.     (void) putchar(c);
  355. }
  356.  
  357. void
  358. putstr(s)
  359. register const char *s;
  360. {
  361.     while(*s) putsym(*s++);
  362. }
  363.  
  364. #endif /* OVL0 */
  365. #ifdef OVL2
  366.  
  367. char
  368. yn_function(resp, def)
  369. const char *resp;
  370. char def;
  371. /*
  372.  *   Generic yes/no function
  373.  */
  374. {
  375.     register char q;
  376.     char rtmp[8];
  377.  
  378.     Sprintf(rtmp, "[%s] ", resp);
  379.     addtopl(rtmp);
  380.  
  381.     do {
  382.         q = lowc(readchar());
  383.  
  384.         if (index(quitchars, q)) q = def;
  385.         else if (!index(resp, q)) {
  386.             bell();
  387.             q = (char)0;
  388.         }
  389.     } while(!q);
  390.  
  391.     Sprintf(rtmp, "%c", q);
  392.     addtopl(rtmp);
  393.     flags.toplin = 2;
  394.  
  395.     return q;
  396. }
  397.  
  398. #endif /* OVL2 */
  399. #ifdef OVLB
  400.  
  401. /*VARARGS1*/
  402. void
  403. impossible VA_DECL(const char *, s)
  404.     VA_START(s);
  405.     VA_INIT(s, const char *);
  406.     vpline(s,VA_ARGS);
  407.     pline("Program in disorder - perhaps you'd better Quit.");
  408.     VA_END();
  409. }
  410.  
  411. #endif /* OVLB */
  412.